package cn.newgrand.netcall.muc;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SimpleTimeZone;

import javax.swing.BorderFactory;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.UIManager;

import org.jivesoftware.resource.Res;
import org.jivesoftware.resource.SparkRes;
import org.jivesoftware.smack.SmackConfiguration;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smackx.Form;
import org.jivesoftware.smackx.FormField;
import org.jivesoftware.smackx.ServiceDiscoveryManager;
import org.jivesoftware.smackx.muc.Affiliate;
import org.jivesoftware.smackx.muc.DiscussionHistory;
import org.jivesoftware.smackx.muc.HostedRoom;
import org.jivesoftware.smackx.muc.MultiUserChat;
import org.jivesoftware.smackx.muc.RoomInfo;
import org.jivesoftware.smackx.packet.DataForm;
import org.jivesoftware.smackx.packet.DiscoverInfo;
import org.jivesoftware.spark.ChatManager;
import org.jivesoftware.spark.SparkManager;
import org.jivesoftware.spark.component.VerticalFlowLayout;
import org.jivesoftware.spark.plugin.ContextMenuListener;
import org.jivesoftware.spark.ui.conferences.ConferenceRoomBrowser;
import org.jivesoftware.spark.ui.conferences.RoomCreationDialog;
import org.jivesoftware.spark.ui.rooms.GroupChatRoom;
import org.jivesoftware.spark.util.ModelUtil;
import org.jivesoftware.spark.util.SwingWorker;
import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.LocalPreferences;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;

import cn.newgrand.common.NetcallUtil;
import cn.newgrand.netcall.component.BaseItem;
import cn.newgrand.netcall.muc.ChinaGroupItem;
import cn.newgrand.netcall.muc.ChinaGroupItemGroup;

/**
 * 群管理界面
 * 
 * @author SidneyRen E-mail:SidneyRen@hotmail.com
 * @version create time：2010-11-4 下午08:03:29
 */
public class ChinaGroupUI extends JPanel{
	private static final long                  serialVersionUID  = 1L;
	
	private boolean partialDiscovery = false;
	
    private JPanel                             mainPanel         = new JPanel();
    private JScrollPane                        itemScrollPane;
    
//    private AppSysMenuHandler menuHandler = IntegrationManager.getAppSysMenuHandler();
    private final List<ChinaGroupItemGroup> groupList     = new ArrayList<ChinaGroupItemGroup>();
    private final Map<String,ChinaGroupItemGroup> groupMap = new HashMap<String, ChinaGroupItemGroup>();

    public static KeyEvent                     activeKeyEvent;

    private final List<ContextMenuListener>    contextListeners  = new ArrayList<ContextMenuListener>();
    private ChinaGroupItemGroup joinedGroup = new ChinaGroupItemGroup("我参加的群");
    
    private ChatManager chatManager;
    private static Map<String,MultiUserChat> multiUserChatMap = new HashMap<String,MultiUserChat>(); 
    
    private ChinaGroupManager chinaGroupManager = ChinaGroupManager.getInstance();
    private Map<String,GroupChatRoom> chinaGroupMap = chinaGroupManager.getCachedChinaGroups();

    //判断服务端chinagroup服务是否存在
    private boolean isChinaGroupExist = false;
    
    //判断是否已经创建过一个群
    private boolean createdGroup = false;
    
    public ChinaGroupUI(){
        setLayout(new BorderLayout());
        
        mainPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true, false));
        mainPanel.setBackground((Color) UIManager.get("ContactItem.background"));
        
        itemScrollPane = new JScrollPane(mainPanel);
        itemScrollPane.setAutoscrolls(true);
        itemScrollPane.setBorder(BorderFactory.createEmptyBorder());
        itemScrollPane.getVerticalScrollBar().setBlockIncrement(50);
        itemScrollPane.getVerticalScrollBar().setUnitIncrement(20);
        
        
        
        add(itemScrollPane, BorderLayout.CENTER);
        
        mainPanel.addMouseListener(new MouseAdapter() {
			public void mousePressed(MouseEvent e) {
				checkPopup(e);
			}

			public void mouseReleased(MouseEvent e) {
				checkPopup(e);
			}

			public void checkPopup(MouseEvent e) {
				if (e.isPopupTrigger()) {
					e.consume();
					final JPopupMenu popup = new JPopupMenu();

					JMenuItem searchGroup;
				    JMenuItem createGroup;
					searchGroup = new JMenuItem("查找群");
			        createGroup = new JMenuItem("创建群");
			        searchGroup.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							searchChinaGroup();
						}
					});
			        createGroup.addActionListener(new ActionListener() {
						public void actionPerformed(ActionEvent e) {
							if(isChinaGroupExist)
								createChinaGroup();
						}
					});
			        popup.add(searchGroup);
			        popup.addSeparator();
			        popup.add(createGroup);
			        popup.show(mainPanel,e.getX(),e.getY());
//					fireContactGroupPopupEvent(e);
				}
			}
		});
        initialize();
    }

    public void initialize(){
    	chatManager = SparkManager.getChatManager();
    	initGroupPanel();
    	buildJoinedGroup();
    }
    /**
     * 添加“我参加的群”到面板中
     */
    private void initGroupPanel(){
    	addGroupItem(joinedGroup);
    	joinedGroup.setVisible(true);
    }
    
    public void buildJoinedGroup(){
    	 SwingWorker worker = new SwingWorker() {
    		 Collection rooms ;
             public Object construct() {
                 try {
                     rooms = MultiUserChat.getHostedRooms(SparkManager.getConnection(),MUCUtil.getChinaGroupServiceName());
                     isChinaGroupExist =true;
                 }
                 catch (Exception e) {
                     Log.error("Unable to retrieve list of rooms.", e);
                 }

                 return "OK";
             }

             public void finished() {
                 if (rooms == null) {
                     JOptionPane.showMessageDialog(itemScrollPane, Res.getString("message.conference.info.error"), Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
//                     if (dlg != null) {
//                         dlg.dispose();
//                     }
                 }
                 try {
                     for (Object room : rooms) {
                         HostedRoom hostedRoom = (HostedRoom) room;
                         String roomName = hostedRoom.getName();
                         String roomJID = hostedRoom.getJid();

                         int numberOfOccupants = -1;
                         
                         String userOfflineDate = "";
                         // Need to handle the case where the room info does not contain the number of occupants. If that is the case,
                         // we should not continue to request this info from the service.
                         if (!partialDiscovery) {
                             RoomInfo roomInfo = null;
                             try {
                                 roomInfo = MultiUserChat.getRoomInfo(SparkManager.getConnection(), roomJID);
                             }
                             catch (Exception e) {
                                 // Nothing to do
                             }

                             if (roomInfo != null) {
                                 numberOfOccupants = roomInfo.getOccupantsCount();
                                 
                                 userOfflineDate = roomInfo.getUserOfflineDate();
                             }
                             if (roomInfo == null || numberOfOccupants == -1) {
                                 partialDiscovery = true;
                             }
                         }
                         joinedGroup.addItem(new ChinaGroupItem(roomJID, roomName,null));
                         
                         //加载多人聊天信息到内存
                         //loadMultiUserChat(roomJID);
                         if(!userOfflineDate.equals(""))
                        	 loadMultiUserChat(roomJID,userOfflineDate,roomName);
                         else
                        	 loadMultiUserChat(roomJID);
                         
                     }
//                     if(rooms.size()==0){
//                    	 joinedGroup.addItem(noItem);
//                     }else{
//                    	 
//                     }
                 }
                 catch (Exception e) {
                     Log.error("Error setting up GroupChatTable", e);
                 }
             }
         };

         worker.start();
    }

    /**
     * 加载所有参与的群信息,包括
     * smack保存信息
     */
    private void loadMultiUserChat() {
//    	for (BaseItem item : joinedGroup.getItems()) {
//    		joinRoom(item.getID());
//		}
	}
    
    /**
     * 加载群信息到smack中
     * @param roomJID
     */
    private void loadMultiUserChat(final String roomJID) {
    	final List<String> errors = new ArrayList<String>();
    	final MultiUserChat groupChat = new MultiUserChat(SparkManager.getConnection(), roomJID);
    	final GroupChatRoom room = new GroupChatRoom(groupChat);
        room.setTabTitle(NetcallUtil.getUserOrRoomName(roomJID));
    	final SwingWorker startChat = new SwingWorker() {
            public Object construct() {
                if (!groupChat.isJoined()) {
                    int groupChatCounter = 0;
                    while (true) {
                        groupChatCounter++;
                        String joinName = SparkManager.getUserManager().getNickname();
//                        if (groupChatCounter > 1) {
//                            joinName = joinName + groupChatCounter;
//                        }
//                        if (groupChatCounter < 10) {
                            try {
                                groupChat.join(joinName);
                                break;
                            }
                            catch (XMPPException ex) {
                                int code = 0;
                                if (ex.getXMPPError() != null) {
                                    code = ex.getXMPPError().getCode();
                                }

                                if (code == 0) {
                                    errors.add("No response from server.");
                                }
                                else if (code == 401) {
                                    errors.add("The password did not match the rooms password.");
                                }
                                else if (code == 403) {
                                    errors.add("You have been banned from this room.");
                                }
                                else if (code == 404) {
                                    errors.add("The room you are trying to enter does not exist.");
                                }
                                else if (code == 407) {
                                    errors.add("You are not a member of this room.\nThis room requires you to be a member to join.");
                                }
                                else if (code != 409) {
                                    break;
                                }
                            }
//                        }
//                        else {
//                            break;
//                        }
                    }
                }
                return "ok";
            }

            public void finished() {
                if (errors.size() > 0) {
//                    String error = errors.get(0);
                    JOptionPane.showMessageDialog(SparkManager.getMainWindow(),"加载"+roomJID.substring(0,roomJID.indexOf('@'))+"群时出错", Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
                }
                else if (groupChat.isJoined()) {
//                	multiUserChatMap.put(roomJID, groupChat);
                	chinaGroupManager.cacheChinaGroup(room);
                	room.getConferenceRoomInfo().initMemebersInfo();
                }
                else {
                    JOptionPane.showMessageDialog(SparkManager.getMainWindow(), "群"+roomJID.substring(0,roomJID.indexOf('@'))+"不存在",  Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
                }
            }
        };

        startChat.start();
	}
    
    /**
     * 加载群信息到smack中, 
     * @param roomJID
     */
    private void loadMultiUserChat(final String roomJID,final String userOfflineTime,String roomName) {
    	final List<String> errors = new ArrayList<String>();
    	final MultiUserChat groupChat = new MultiUserChat(SparkManager.getConnection(), roomJID);
    	final GroupChatRoom room = new GroupChatRoom(groupChat);
        //room.setTabTitle(NetcallUtil.getUserOrRoomName(roomJID));
    	room.setTabTitle(roomName);
    	final SwingWorker startChat = new SwingWorker() {
            public Object construct() {
                if (!groupChat.isJoined()) {
                    int groupChatCounter = 0;
                    while (true) {
                        groupChatCounter++;
                        String joinName = SparkManager.getUserManager().getNickname();
                        String nickName = groupChat.getReservedNickname(SparkManager.getSessionManager().getJID());
                        if(!ModelUtil.hasLength(nickName)){
                        	nickName = joinName;
                        }
//                        if (groupChatCounter > 1) {
//                            joinName = joinName + groupChatCounter;
//                        }
//                        if (groupChatCounter < 10) {
                            try {
                                groupChat.join(nickName, null,getOfflineDate(userOfflineTime) ,SmackConfiguration.getPacketReplyTimeout());
                                break;
                            }
                            catch (XMPPException ex) {
                                int code = 0;
                                if (ex.getXMPPError() != null) {
                                    code = ex.getXMPPError().getCode();
                                }

                                if (code == 0) {
                                    errors.add("No response from server.");
                                }
                                else if (code == 401) {
                                    errors.add("The password did not match the rooms password.");
                                }
                                else if (code == 403) {
                                    errors.add("You have been banned from this room.");
                                }
                                else if (code == 404) {
                                    errors.add("The room you are trying to enter does not exist.");
                                }
                                else if (code == 407) {
                                    errors.add("You are not a member of this room.\nThis room requires you to be a member to join.");
                                }
                                else if (code != 409) {
                                    break;
                                }
                            }
//                        }
//                        else {
//                            break;
//                        }
                    }
                }
                return "ok";
            }

            public void finished() {
                if (errors.size() > 0) {
//                    String error = errors.get(0);
                    JOptionPane.showMessageDialog(SparkManager.getMainWindow(),"加载"+roomJID.substring(0,roomJID.indexOf('@'))+"群时出错", Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
                }
                else if (groupChat.isJoined()) {
//                	multiUserChatMap.put(roomJID, groupChat);
                	chinaGroupManager.cacheChinaGroup(room);
                	room.getConferenceRoomInfo().initMemebersInfo();
                }
                else {
                    JOptionPane.showMessageDialog(SparkManager.getMainWindow(), "群"+roomJID.substring(0,roomJID.indexOf('@'))+"不存在",  Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
                }
            }
        };

        startChat.start();
	}
    
    /**
     * modified
     * @param time
     * @return
     */
    private DiscussionHistory getOfflineDate(String time)  {
        DateFormat dateFormatter = new SimpleDateFormat("yyyyMMdd'T'HH:mm:ss");
        DiscussionHistory history = new DiscussionHistory();
        try
        {
	        Date date = dateFormatter.parse(time);
	        Calendar a = Calendar.getInstance();
	        a.setTime(date);
	        a.add(Calendar.HOUR_OF_DAY, 8);
	    	history.setSince(a.getTime());
        }
        catch(ParseException ex)
        {
        	history = null;
        	Log.warning("data format error ,history will be null and client will receive all message",ex);
        }
        return history;
    }
    
    
//    public static Map<String,MultiUserChat> getMultiUserChatMap(){
//    	return multiUserChatMap;
//    }
    /**
     * Adds a new ContactGroup to the ContactList.
     *
     * @param group the group to add.
     */
    private void addGroupItem(ChinaGroupItemGroup group) {
        groupList.add(group);

        Collections.sort(groupList, GROUP_COMPARATOR);

        try {
            mainPanel.add(group, groupList.indexOf(group));
        }
        catch (Exception e) {
            Log.error(e);
        }
    }
    /**
     * 添加一个群到群面板中
     * 
     * @param name
     * @param room
     * @param url
     */
    public void addChinaGroupItem(String name,String room,String url){
    	joinedGroup.addItem(new ChinaGroupItem(room, name, url));
    }
    
    /**
     * 在群面板中删除群
     * @param id
     */
    public void removeChinaGroupItem(String id){
    	joinedGroup.removeItem(id);
    }
    
    public void removeAllChinaGroupItem()
    {
    	for(BaseItem bi :joinedGroup.getItems())
    	{
    		removeChinaGroupItem(bi.getName());
    	}
    }
    
    /**
     * Sorts ContactGroups
     */
    public static final Comparator<ChinaGroupItemGroup> GROUP_COMPARATOR = new Comparator<ChinaGroupItemGroup>() {
        public int compare(ChinaGroupItemGroup group1, ChinaGroupItemGroup group2) {
            return group1.getGroupName().trim().toLowerCase().compareTo(group2.getGroupName().trim().toLowerCase());
        }
    };
    
    public void createChinaGroup(){
    	//TODO 最多只能创建一个群
    	if(createdGroup){
    		JOptionPane.showMessageDialog(this, "创建群失败，每个用户最多只能创建一个群", Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
    		return ;
    	}
    	for (Entry<String,GroupChatRoom> entry : chinaGroupMap.entrySet()) {
			for(String str:((GroupChatRoom)(entry.getValue())).getConferenceRoomInfo().getAdmins()){
				if(str.equals(SparkManager.getSessionManager().getBareAddress())){
					createdGroup = true;
					JOptionPane.showMessageDialog(this, "创建群失败，每个用户最多只能创建一个群", Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
					return;
				}
			}
		}
    	
    	String roomName = JOptionPane.showInputDialog(this, "群名称:", "创建一个群", JOptionPane.QUESTION_MESSAGE);
        if (ModelUtil.hasLength(roomName)) {
        String tempRoomID = roomName.replaceAll(" ", "_") + "@" +  MUCUtil.chinaGroupServiceName;

        // Create a group chat with valid information
        
        
//            RoomCreationDialog mucRoomDialog = new RoomCreationDialog();
//            final MultiUserChat groupChat = mucRoomDialog.createGroupChat(SparkManager.getMainWindow(), MUCUtil.chinaGroupServiceName);
            final MultiUserChat groupChat = new MultiUserChat(SparkManager.getConnection(), tempRoomID.toLowerCase());
            LocalPreferences pref = SettingsManager.getLocalPreferences();

            if (null != groupChat) {
                // Join Room
                try {
                    groupChat.create(pref.getNickname());
                    GroupChatRoom room = new GroupChatRoom(groupChat);
                    //modified by sww  在创建群的是增加查看聊天记录的按钮.
                    SparkManager.getWorkspace().getTranscriptPlugin().getChatRoomDecorator(room);
                    chatManager.getChatContainer().addChatRoom(room);
                    chatManager.getChatContainer().activateChatRoom(room);

                    // 配置群属性
                    Form form = groupChat.getConfigurationForm().createAnswerForm();
                    form.setAnswer("muc#roomconfig_roomname",roomName);
                    form.setAnswer("muc#roomconfig_persistentroom", true);
                    List<String> owners = new ArrayList<String>();
                    owners.add(SparkManager.getSessionManager().getBareAddress());
                    form.setAnswer("muc#roomconfig_roomowners", owners);
                    form.setAnswer("muc#roomconfig_membersonly", true);
                    form.setAnswer("muc#roomconfig_allowinvites", false);
                    // new DataFormDialog(groupChat, form);
                    groupChat.sendConfigurationForm(form);

                    //初始化群聊成员信息
                    room.getConferenceRoomInfo().initMemebersInfo();
                    //在群显示面板中添加一个该群的项
                    joinedGroup.addItem(new ChinaGroupItem(tempRoomID.toLowerCase(), roomName.replaceAll(" ", "_"), null));
                    //将群内容缓存到客户端 chinaGroupMap
                    ChinaGroupManager.getInstance().cacheChinaGroup(room);
                }
                catch (XMPPException e1) {
                	if(e1.getXMPPError().getCode() == 405){
                		JOptionPane.showMessageDialog(this, "权限不足无法创建,请通知管理员授权", Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
                	}else{
                		JOptionPane.showMessageDialog(this, "创建群失败,该群名已经被注册", Res.getString("title.error"), JOptionPane.ERROR_MESSAGE);
                	}
                }
            }
        }
    }
    public void searchChinaGroup(){
    	String roomName = JOptionPane.showInputDialog(this, "群名称:", "查找群", JOptionPane.QUESTION_MESSAGE);
        if (ModelUtil.hasLength(roomName)) {
        	SearchGroupUI rooms = new SearchGroupUI(null, MUCUtil.chinaGroupServiceName);
        	rooms.invoke(roomName);
        }
    }
}

    
